package cn.tedu.store.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.PhoneUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.tedu.store.config.QRCode.QRCodeUtil;
import cn.tedu.store.config.util.RedisService;
import cn.tedu.store.entity.*;
import cn.tedu.store.entity.dto.MeetingCheckRecodeDto;
import cn.tedu.store.service.IMeetingService;
import cn.tedu.store.service.MeetingCheckRecodeDtoService;
import cn.tedu.store.temperatureDetection.entity.dto.EmployeeDto;
import cn.tedu.store.util.BaseQuery;
import cn.tedu.store.util.JsonResult;
import cn.tedu.store.util.PageList;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import sun.misc.BASE64Decoder;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;

@RestController
@Slf4j
@RequestMapping(value = "/meeting")
public class MeetingController extends BaseController {

    //根据code获取微信小程序openid
    private static final String WECHAT_MP_GET_OPENID_URL = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code";

    @Autowired
    IMeetingService meetingService;
    @Autowired
    MeetingCheckRecodeDtoService meetingCheckRecodeDtoService;



    //通过电话号码获取人员信息
    @GetMapping(value = "/selectEmployee")
    public Object selectEmployee(String phone) {
        return new JsonResult<>(200, meetingService.selectEmployee(phone));
    }

    @GetMapping(value = "/selectDept")
    public Object selectDept() {
        return new JsonResult<>(200, meetingService.selectDepartment());
    }

    //获取会议编号
    @GetMapping(value = "/getMeetingCode")
    public Object meetingCode() {
        return new JsonResult<>(200, meetingService.meetingCode());
    }

    @PostMapping(value = "/meetingRecodeInsert")
    public JsonResult meetingInsert(@RequestBody(required = false) MeetingCheckRecode meetingCheckRecode) {
        meetingService.insert_MeetingRecode(meetingCheckRecode);
//        if (meetingCheckRecode==null){
//            return new JsonResult<>(400, null);
//        }else {
//            return new JsonResult<>(200, null);
//        }
        return new JsonResult<>(200, null);
    }

    // 获得微信小程序手机号和tk
    @PostMapping("/getWechatMpPhoneAndTk")
    @Transactional
    public Object getWechatMpPhoneAndTk(@RequestBody MpDto dto) {
        Object r = getWechatMpPhone(dto);
        return new JsonResult<>(200, r);
    }
    @PostMapping("/getPhone")
    @Transactional
    public Object Phone(@RequestBody MpDto dto) {
        Object r = getPhone(dto);
        return new JsonResult<>(200, r);
    }
    public Object getPhone(@RequestBody MpDto dto) {
        JSONObject object = null;
        try {
            String url = String.format(WECHAT_MP_GET_OPENID_URL, "wxbe061859f1488b2c", "9fb219fca221c7f51eedc6d7f1dad9d4", dto.getCode());
            //log.info("request accessToken from url: {}", url);
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet(url);
            HttpResponse httpResponse = httpClient.execute(httpGet);
            HttpEntity httpEntity = httpResponse.getEntity();
            String tokens = EntityUtils.toString(httpEntity, "utf-8");
            object = JSONUtil.parseObj(tokens);
            //log.info("request accessToken success. [result={}]", object);
            if (!object.keySet().contains("openid")) {
                throw new RuntimeException("未能获得openid");
            }
            String session_key = object.get("session_key").toString().replaceAll("\"", "");
            //解密，返回解析的json字符串
            String decryData = getPhoneNumberBeanS5(dto.getEncryptedData(), session_key, dto.getIv());
            if (decryData == null) {
                throw new RuntimeException("数据异常：" + decryData);
            }
            // json字符串格式:{"phoneNumber":"18608608556","purePhoneNumber":"18608608556","countryCode":"86","watermark":{"timestamp":1615428996,"appid":"wx41a933510fdcf838"}}
            // 通过json解析工具列，将json字符串解析成json对象
            JSONObject phoneObj = JSONUtil.parseObj(decryData);
            // 从json对象中通过key获取对应的值（phoneNumber = 18888888888）
            String phoneNumber = phoneObj.getStr("phoneNumber");
            // 验证手机号
            boolean phone = PhoneUtil.isPhone(phoneNumber);
            if (!phone) {
                throw new RuntimeException("手机号码错误");
            }

            // 查询不到数据返回
            return new JsonResult<>(200, phone);
        } catch (Exception ex) {
            throw new RuntimeException("fail to request wechat access token. [error={}]", ex);
        }
    }

    public Object getWechatMpPhone(@RequestBody MpDto dto) {
        JSONObject object = null;
        try {
            String url = String.format(WECHAT_MP_GET_OPENID_URL, "wxbe061859f1488b2c", "9fb219fca221c7f51eedc6d7f1dad9d4", dto.getCode());
            //log.info("request accessToken from url: {}", url);
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet(url);
            HttpResponse httpResponse = httpClient.execute(httpGet);
            HttpEntity httpEntity = httpResponse.getEntity();
            String tokens = EntityUtils.toString(httpEntity, "utf-8");
            object = JSONUtil.parseObj(tokens);
            //log.info("request accessToken success. [result={}]", object);
            if (!object.keySet().contains("openid")) {
                throw new RuntimeException("未能获得openid");
            }
            String session_key = object.get("session_key").toString().replaceAll("\"", "");
            //解密，返回解析的json字符串
            String decryData = getPhoneNumberBeanS5(dto.getEncryptedData(), session_key, dto.getIv());
            if (decryData == null) {
                throw new RuntimeException("数据异常：" + decryData);
            }
            // json字符串格式:{"phoneNumber":"18608608556","purePhoneNumber":"18608608556","countryCode":"86","watermark":{"timestamp":1615428996,"appid":"wx41a933510fdcf838"}}
            // 通过json解析工具列，将json字符串解析成json对象
            JSONObject phoneObj = JSONUtil.parseObj(decryData);
            // 从json对象中通过key获取对应的值（phoneNumber = 18888888888）
            String phoneNumber = phoneObj.getStr("phoneNumber");
            // 验证手机号
            boolean phone = PhoneUtil.isPhone(phoneNumber);
            if (!phone) {
                throw new RuntimeException("手机号码错误");
            }
            // 通过手机号查询人员信息
            List<Employee> employees = meetingService.selectEmployee(phoneNumber);
            if (CollUtil.isNotEmpty(employees)) {
                // 查询到信息，从这里返回数据结束，不会走下面
                //return new JsonResult<>(200, employees.get(0));
                return employees.get(0);
            }
            // 查询不到数据返回
            return new JsonResult<>(500, null);
        } catch (Exception ex) {
            throw new RuntimeException("fail to request wechat access token. [error={}]", ex);
        }
    }

    public String getPhoneNumberBeanS5(String decryptData, String key, String iv) throws Exception {
        /*
         *这里你没必要非按照我的方式写，下面打代码主要是在一个自己的类中 放上decrypts5这个解密工具，工具在下方有代码
         */
        // 这里解析成了一个JSON的字符串
        String resultMessage = decryptS5(decryptData, "UTF-8", key, iv);
        return resultMessage;
    }

    /**
     * 解密工具直接放进去即可
     */
    public static String decryptS5(String sSrc, String encodingFormat, String sKey, String ivParameter) throws Exception {
        try {
            BASE64Decoder decoder = new BASE64Decoder();
            byte[] raw = decoder.decodeBuffer(sKey);
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            IvParameterSpec iv = new IvParameterSpec(decoder.decodeBuffer(ivParameter));
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
            byte[] myendicod = decoder.decodeBuffer(sSrc);
            byte[] original = cipher.doFinal(myendicod);
            String originalString = new String(original, encodingFormat);
            return originalString;
        } catch (Exception ex) {
            return null;
        }
    }


    @PostMapping("signMeeting")
    public JsonResult<MeetingCheckRecodeDto> signMeeting(@RequestBody MeetingCheckRecodeDto meetingCheckRecodeDto){
        return new JsonResult<>(200,meetingService.signMeeting(meetingCheckRecodeDto));
    }


    @PostMapping(value = "/getQRCode")
    public JsonResult getQRCode(@RequestBody Meeting meeting){
        meetingService.insertMeeting(meeting);
        String code = QRCodeUtil.getCode(meeting.getMeetingCode());
        log.info("二维码输出的内容为{}",code);
        return new JsonResult(200,code);
    }


    @GetMapping("getMeetingName")
    public JsonResult getMeetingName( String mCode){
        Meeting meetingName = meetingService.getMeetingName(mCode);
        return new JsonResult<>(200,meetingName);

    }


    //获取会议编号和地址信息进行签到
    //@PostMapping("getMeetingCheckRecodeDto")
    //public JsonResult getMeetingCheckRecodeDto(@RequestBody MeetingCheckRecodeDto meetingCheckRecodeDto) {
    //    log.info("获取会议的编号和地址信息进行签到{}",meetingCheckRecodeDto);
    //    meetingCheckRecodeDtoService.getMeetingCheckRecodeDto(meetingCheckRecodeDto);
    //    return new JsonResult(200);
    //{
    //    "mCode":"202208170101",
    //        "lng":"114.407765",
    //        "lat":"30.491252"
    //}
    //}1
    @GetMapping("getMeetingCheckRecodeDto")
    public JsonResult getMeetingCheckRecodeDto(@RequestParam("mCode")String mCode,
                                               @RequestParam("lng") Double lng,
                                               @RequestParam("lat") Double lat,
                                               @RequestParam("iphone") String iphone,
                                               @RequestParam("code") String code
                                               ) {
        log.info("获取会议的编号和地址信息进行签到{}",mCode);
        meetingCheckRecodeDtoService.getMeetingCheckRecodeDto(mCode,lat,lng,iphone,code);
        return new JsonResult(200);
    }
    //获取已经签到的人员信息接口
    @GetMapping("findSingInEmployee")
    public JsonResult findSingInEmployee(String meetingCode, BaseQuery baseQuery) {
        log.info("获取已经签到的人员信息接口{}",meetingCode);
        PageList<EmployeeDto> employeePageList = meetingService.selectEmployeeName(meetingCode, baseQuery);
        return new JsonResult(200,employeePageList);
    }

    @GetMapping("getOutSideCheckRecodeDto")
    public JsonResult getOutSideMeetingCheckRecodeDto(@RequestParam("mCode")String mCode,
                                                      @RequestParam("name")String name,
                                                      @RequestParam("lng") Double lng,
                                                      @RequestParam("lat") Double lat,
                                                      @RequestParam("iphone") String iphone,
                                                      @RequestParam("code") String code,
                                                      @RequestParam("add") String add){
        String keyObjectValue = redisService.getKeyObjectValue(mCode+code, String.class);
        System.out.println(keyObjectValue);
        if (!Objects.equals(code, keyObjectValue)){
            throw new RuntimeException("二维码已经过期，请重新扫面二维码");
        }
        log.info("院外员工签到",mCode);
        meetingCheckRecodeDtoService.getOutSideMeetingCheckRecodeDto(mCode,lat,lng,iphone,code,name,add);
        return new JsonResult(200);
    }

    @GetMapping("getEmplCodeCheck")
    public JsonResult getEmplCodeCheck(@RequestParam("mCode")String mCode,
                                       @RequestParam("lng") Double lng,
                                       @RequestParam("lat") Double lat,   @RequestParam("code") String code,
                                       @RequestParam("pCode") String pCode){
        log.info("员工号签到",mCode);
        String keyObjectValue = redisService.getKeyObjectValue(mCode+code, String.class);
        System.out.println(keyObjectValue);
        if (!Objects.equals(code, keyObjectValue)){
            throw new RuntimeException("二维码已经过期，请重新扫面二维码");
        }
        meetingCheckRecodeDtoService.getEmplCodeCheck(mCode,lng,lat,code,pCode);
        return new JsonResult(200);
    }
    @GetMapping("getEmplCodeCheckReplace")
    public JsonResult getEmplCodeCheck(@RequestParam("mCode")String mCode,
                                       @RequestParam("lng") Double lng,
                                       @RequestParam("lat") Double lat,   @RequestParam("code") String code,
                                       @RequestParam("pCode") String pCode,@RequestParam("name2")String name2){
        log.info("员工号替签",mCode);
        String keyObjectValue = redisService.getKeyObjectValue(mCode+code, String.class);

        if (!Objects.equals(code, keyObjectValue)){
            throw new RuntimeException("二维码已经过期，请重新扫面二维码");
        }
        meetingCheckRecodeDtoService.getEmplCodeCheckReplace(mCode,lng,lat,code,pCode,name2);
        return new JsonResult(200);
    }
    //获取迟到员工的姓名
    @GetMapping("getLateEmployee")
    public JsonResult getLateEmployee(String meetingCode, BaseQuery baseQuery){
        log.info("和获取迟到员工的姓名");
        PageList<EmployeeDto> employeeDtoPageList = meetingService.selectLateEmployee(meetingCode, baseQuery);
        return new JsonResult(200, employeeDtoPageList);
    }

    @GetMapping("getnotSingInEmployee")
    public JsonResult getnotSingInEmployee(String meetingCode,BaseQuery baseQuery){
        log.info("获取未签到员工的姓名");
        PageList<EmployeeDto> employeeDtoPageList = meetingService.selectNotSingInEmployee(meetingCode, baseQuery);
        return new JsonResult(200,employeeDtoPageList);
    }

    @PostMapping("addMeeting")
    public JsonResult addMeeting(@RequestBody Meeting meeting){
        log.info("新增会议");
        meetingService.insertMeeting(meeting);
        return new JsonResult(200);
    }

    @Autowired
    RedisService redisService;
    //替签接口
    @GetMapping("getMeetingCheckRecodeReplace")
    public JsonResult getMeetingCheckRecodeReplace
            (@RequestParam("mCode")String mCode,
            @RequestParam("name")String name,
            @RequestParam("lng") Double lng,
            @RequestParam("lat") Double lat,
            @RequestParam("iphone") String iphone,
            @RequestParam("code") String code)
    {
        String keyObjectValue = redisService.getKeyObjectValue(mCode+code, String.class);

        if (!Objects.equals(code, keyObjectValue)){
            throw new RuntimeException("二维码已经过期，请重新扫面二维码");
        }

//        if (!Objects.isNull(keyObjectValue)){
//            throw new RuntimeException("二维码已经过期，请重新扫面二维码");
//        }

        meetingCheckRecodeDtoService.replace(mCode,lat,lng,iphone,code,name);
        return new JsonResult(200);
    }

    //员外代签
    @GetMapping("getMeetingRunderCheckRecodeReplace")
    public JsonResult getMeetingRunderCheckRecodeReplace
    (@RequestParam("mCode")String mCode,
     @RequestParam("name")String name,
     @RequestParam("name2")String name2,
     @RequestParam("lng") Double lng,
     @RequestParam("lat") Double lat,
     @RequestParam("iphone") String iphone,
     @RequestParam("code") String code)
    {


        String keyObjectValue = redisService.getKeyObjectValue(mCode+code, String.class);
        System.out.println(keyObjectValue);
        if (!Objects.equals(code, keyObjectValue)){
            throw new RuntimeException("二维码已经过期，请重新扫面二维码");
        }

        meetingCheckRecodeDtoService.replace2(mCode,lat,lng,iphone,code,name,name2);
        return new JsonResult(200);
    }

//    //员工搜索接口
//    @GetMapping("getList")
//    public JsonResult getList(){
//        List<String> names =   meetingCheckRecodeDtoService.getList();
//        return new JsonResult(200,names);
//    }

    //员工请假
    @GetMapping("leave")
    public JsonResult leave(
            @RequestParam("mCode")String mCode, @RequestParam("iphone") String iphone
    ){

        meetingCheckRecodeDtoService.update(mCode,iphone);
        return new JsonResult(200);
    }

    //员工会议展示
    @GetMapping("allMeeting")
    public  JsonResult allMeeting(
            @RequestParam("iphone") String iphone
    ){
            List<SMeetingcheckrecode> all = meetingCheckRecodeDtoService.getAll(iphone);
        for (SMeetingcheckrecode sMeetingcheckrecode : all) {
            System.out.println(sMeetingcheckrecode.getPValidity());
            if(    sMeetingcheckrecode.getPValidity().equals("1")){
                sMeetingcheckrecode.setPValidity("已签到");
            }else if (sMeetingcheckrecode.getPValidity().equals("0")){
                sMeetingcheckrecode.setPValidity("未签到");
            }else  if(sMeetingcheckrecode.getPValidity().equals("2")){
                sMeetingcheckrecode.setPValidity("迟到");
            }else  if (sMeetingcheckrecode.getPValidity().equals("3")){
                sMeetingcheckrecode.setPValidity("请假");
            }else if (sMeetingcheckrecode.getPValidity().equals("5")){
                sMeetingcheckrecode.setPValidity("审批中");
            }
        }
        Stream<SMeetingcheckrecode> sMeetingcheckrecodeStream = all.stream().filter(s -> !s.getPValidity().equals("4"));

        return new JsonResult(200,sMeetingcheckrecodeStream);
    }
}
